package com.pro.common.service.user.service;

import com.pro.common.api.auth.IUserService;
import com.pro.common.api.enums.EnumSysRole;
import com.pro.common.api.model.ILoginInfo;
import com.pro.common.api.model.request.ILoginRequest;
import com.pro.common.api.service.IInviteCodeService;
import com.pro.common.api.user.model.db.User;
import com.pro.common.service.user.dao.UserDao;
import com.pro.framework.api.database.IContext;
import com.pro.framework.api.util.CollUtils;
import com.pro.framework.api.util.PasswordUtils;
import com.pro.framework.api.util.StrUtils;
import com.pro.framework.mybatisplus.BaseService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

//@Service(CommonConst.Bean.userService)
@Slf4j
@Getter
public class UserSimpleService<M extends UserDao<T>, T extends User> extends BaseService<M, T> implements IUserService<T>, IInviteCodeService {
    private final EnumSysRole sysRole = EnumSysRole.USER;
//    @Autowired
//    private CommonProperties commonProperties;


//    @Override
//    public T getLoginInfo(ILoginRequest loginRequest) {
//        return this.query(loginRequest);
//    }
//
//    @Override
//    public void doAfterLogin(T loginInfo) {
//        this.addIncreaseField(loginInfo.getId(), T::getLoginTimes, 1);
//    }

    //    @Override
    public T query(ILoginRequest loginRequest) {
        if (StrUtils.isNotBlank(loginRequest.getUsername())) {
            return this.lambdaQuery().eq(T::getUsername, loginRequest.getUsername()).one();
        }
        if (StrUtils.isNotBlank(loginRequest.getPhone())) {
            return this.lambdaQuery().eq(T::getPhone, loginRequest.getPhone()).one();
        }
        if (StrUtils.isNotBlank(loginRequest.getEmail())) {
            return this.lambdaQuery().eq(T::getEmail, loginRequest.getEmail()).one();
        }
        return null;
    }
//
//    @Override
//    public T register(String request, String ip, String lang) {
//        T user = JSONUtils.fromString(request, getEntityClass());
//        return register(ip, lang, user);
//    }
//
//    public T register(String ip, String lang, T user) {
//        String username = user.getUsername();
//        EnumRegisterUsernameFrom usernameFrom = EnumRegisterUsernameFrom.MAP.getOrDefault(EnumAuthDict.REGISTER_USERNAME_FROM.getValueCache(), EnumRegisterUsernameFrom.INPUT);
//        switch (usernameFrom) {
//            case INPUT:
//                break;
//            case PHONE:
//                username = user.getPhone();
//                break;
//            case EMAIL:
//                username = user.getEmail();
//                break;
//            default:
//                throw new BusinessException("用户名来源配置错误");
//        }
//        user.setUsername(username);
//
//        user.setEnabled(true);
//        user.setIsDemo(false);
//        user.setLang(lang);
//        user.setRegisterIp(ip);
//
//        this.registerCheck(user);
//
//        if (this.lambdaQuery().eq(T::getUsername, username).count() > 0) {
//            throw new BusinessException("该用户名已经被注册了", username);
//        }
//
//        this.save(user, user);
//

    /// /        TransactionUtil.doAfter(() -> messageService.sendMsgAllChannelType(user, EnumSysMsgBusinessCode.REGISTER_SUCCESS.name(), Collections.singletonMap("user", user), lang, ip, false, false, null));
//        return user;
//    }

//    public void registerCheck(T user) {
//
//    }
//
//    /**
//     * 推荐码
//     */
//    public String buildCode(String letters) {
//        String split = StrUtils.EMPTY;
//        //随机取6位数
//        String code = RandomUtil.randomString(letters, 6);
//        List<String> ss = Arrays.stream(code.split(split)).collect(Collectors.toList());
//        // 顺序打乱
//        Collections.shuffle(ss);
//        code = String.join(split, ss).toUpperCase();
//        String finalCode = code;
//        if (UserOtherService.inviteCodeServices.stream().allMatch(service -> null == service.getByCode(finalCode))) { // 保证唯一性
//            // 没重复,有效推广码
//            return finalCode;
//        }
//        // 重复,重新生成推广码
//        return this.buildCode(letters);
//    }
    @Override
    public List<Long> getIdsByAgentIds(Collection<Long> agentIds) {
        return this.lambdaQuery()
                .select(T::getId)
                .in(T::getAgentId, agentIds)
                .list().stream().map(T::getId).collect(Collectors.toList());
    }

    @Override
    public T getById(Long userId) {
        return super.getById(userId);
    }


    @Override
    public Map<Long, T> idMap(Collection<Long> ids) {
        return super.idMap(ids);
    }

    @Override
    public Map<Long, String> idLangMap(Collection<Long> ids) {
        if (ids.isEmpty()) {
            return Collections.emptyMap();
        }
        List<T> users = this.lambdaQuery().select(T::getId, T::getLang).in(T::getId, ids).list();
        return CollUtils.listToMap(users, T::getId, T::getLang);
    }

//    @Override
//    public T getById(Long userId) {
//        return super.getById(userId);
//    }

    // 更新
    @Override
    public boolean saveOrUpdate(IContext context, T entity) {
        this.doSaveOrUpdate(entity);
        return super.saveOrUpdate(entity);
    }

    @Override
    public boolean updateById(IContext context, T entity) {
        this.doSaveOrUpdate(entity);
        return super.updateById(context, entity);
    }

//    @Override
//    public List<T> listByIds(Collection<? extends Serializable> userIds) {
//        return userIds.isEmpty() ? Collections.emptyList() : super.listByIds(userIds);
//    }

//    @Override
//    public List<T> listByIdsAndLevelIds(Collection<? extends Serializable> userIds, Collection<? extends Serializable> userLevelIds) {
//        return userIds.isEmpty() ? Collections.emptyList() : super.lambdaQuery().in(T::getId, userIds).in(T::getLevelId, userLevelIds).list();
//    }

    //    @Override
    public Map<Long, T> getMap(String queryProp, Collection<?> queryPropValues) {
        return getMap(queryProp, queryPropValues, T::getId);
    }

    @Override
    public List<Long> listIdByPids(List<Long> pids) {
        if (pids.isEmpty()) {
            return Collections.emptyList();
        }
        return this.lambdaQuery()
                .select(User::getId)
                .in(User::getPid, pids).list().stream().map(User::getId)
                .collect(Collectors.toList());
    }

    public void doSaveOrUpdate(T entity) {
        if (StrUtils.isNotBlank(entity.getPassword())) {
            entity.setPassword(PasswordUtils.encrypt_Password(entity.getPassword()));
        }
        if (StrUtils.isNotBlank(entity.getTkPassword())) {
            entity.setTkPassword(PasswordUtils.encrypt_tkPassword(entity.getTkPassword()));
        }
    }

    @Override
    public ILoginInfo getByCode(String code) {
        return this.lambdaQuery().eq(T::getCode, code).one();
    }

//    @Override
//    public IMultiPageResult<T> selectPage(IContext context, String entityClassNames, IPageInput pageInput, Map<String, Object> paramMap, TimeQuery timeQuery) {
//        // 判断并过滤登录用户Id
//        if (this.filterLoginUserIdsReturnEmptyFlag(paramMap)) {
//            return new MultiPageResult<>();
//        }
//
//        return super.selectPage(context, entityClassNames, pageInput, paramMap, timeQuery);
//    }

//    /**
//     * 过滤在线userIds
//     *
//     * @return 在线userId是否为空
//     */
//    private boolean filterLoginUserIdsReturnEmptyFlag(Map<String, Object> paramMap) {
//        Object isOnline = paramMap.get("isOnline");
//        if (null == paramMap.get("id") && isOnline != null) {
//            Set<Long> onlineUserIds = this.getOnlineUserIds();
//            // 在登录列表中
//            if (FrameworkConst.Str.TRUE.equals(isOnline)) {
//                if (onlineUserIds.isEmpty()) {
//                    // 无需额外过滤 直接返回空信息
//                    return true;
//                } else {
//                    paramMap.put("id", "#in#" + onlineUserIds.stream().map(Objects::toString).collect(Collectors.joining("")));
//                }
//            }
//            // 不在登录列表中
//            else if (FrameworkConst.Str.FALSE.equals(isOnline)) {
//                if (onlineUserIds.isEmpty()) {
//                    // 无需额外过滤 继续基础查询
//                    return false;
//                } else {
//                    paramMap.put("id", "#ni#" + onlineUserIds.stream().map(Objects::toString).collect(Collectors.joining("")));
//                }
//            }
//        }
//        return false;
//    }

//    @Override
//    public List<AggregateResult> selectCountSum(IContext context, String entityClassName, IPageInput pageInput, Map<String, Object> paramMap, TimeQuery timeQuery, GroupBy groupBy) {
//        // 判断并过滤登录用户Id
//        if (this.filterLoginUserIdsReturnEmptyFlag(paramMap)) {
//            return Collections.emptyList();
//        }
//        return super.selectCountSum(context, entityClassName, pageInput, paramMap, timeQuery, groupBy);
//    }

//    /**
//     * 获取所有用户端在线人数id集合
//     */
//    public Set<Long> getOnlineUserIds() {
//        Set<Long> userIdList = new HashSet<>(4096);
//        Arrays.stream(StrUtil.blankToDefault(EnumAuthDict.FRONT_API.getValueCache(), EnumAuthDict.FRONT_DOMAIN.getValueCache() + "/api").split(",")).forEach(frontUrl -> {
//            try {
//                String result = HttpUtil.get(frontUrl + "/common" + CommonConst.Str.path_loginUserIds, 10000);
//                if (StrUtil.isNotBlank(result)) {
//                    Object data = JSONUtils.fromString(result, R.class).getData();
//                    if (data instanceof String) {
//                        userIdList.addAll(Arrays.stream(((String) data).split(",")).filter(s -> null != s && s.length() > 0).map(Long::valueOf).collect(Collectors.toSet()));
//                        return;
//                    }
//                }
//                log.warn("获取在线人数失败: {} {}", frontUrl, result);
//            } catch (Exception e) {
//                log.warn("{} 端在线人数异常", frontUrl, e);
//            }
//        });
//        return userIdList;
//    }

    public List<T> listByUsernames(List<String> usernames) {
        if (usernames.isEmpty()) {
            return Collections.emptyList();
        }
        return this.lambdaQuery().in(User::getUsername, usernames).list();
    }
}
